package com.dk.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.dk.data.RedisSeckillGoods;
import com.dk.mapper.seckill.TbSeckillGoodsMapper;
import com.dk.mapper.seckill.TbSeckillOrderMapper;
import com.dk.pojo.seckill.TbSeckillGoods;
import com.dk.pojo.seckill.TbSeckillGoodsExample;
import com.dk.pojo.seckill.TbSeckillOrder;
import com.dk.service.seckill.SeckillGoodsService;
import com.dk.service.seckill.SekillIdAndUserId;
import com.dk.utils.IdWorker;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
@Component
public class SeckillGoodsServiceImpl implements SeckillGoodsService {
    @Resource
    private TbSeckillGoodsMapper seckillGoodsMapper;

    @Resource
    private TbSeckillOrderMapper orderMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public List<TbSeckillGoods> getSeckillGoods() {
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        List<TbSeckillGoods> seckillGoodsList = redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).values();
        if (seckillGoodsList == null || seckillGoodsList.size() <= 0) {
            TbSeckillGoodsExample example = new TbSeckillGoodsExample();
            TbSeckillGoodsExample.Criteria criteria = example.createCriteria();
            criteria.andStatusEqualTo("1");
            criteria.andStartTimeLessThanOrEqualTo(new Date());
            criteria.andEndTimeGreaterThanOrEqualTo(new Date());
            seckillGoodsList = seckillGoodsMapper.selectByExample(example);
            for (TbSeckillGoods seckillGoods : seckillGoodsList) {
                redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).put(seckillGoods.getId(),seckillGoods);
                redisTemplate.boundValueOps(seckillGoods.getId()).set(seckillGoods.getStockCount().toString());
            }
        }
        return seckillGoodsList;
    }

    @Override
    public TbSeckillGoods getSeckillGoodsById(Long id) {
        return (TbSeckillGoods) redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).get(id);
    }

    @Override
    public void submitOrder(Long id, Long userId) {
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        TbSeckillGoods seckillGoods = (TbSeckillGoods) redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).get(id);
        if (seckillGoods == null) {
            throw new RuntimeException("商品不存在");
        }
        if (seckillGoods.getStockCount() <= 0) {
            throw new RuntimeException("商品已售空");
        }
        // 扣减库存
        Integer decrement = Integer.valueOf(redisTemplate.boundValueOps(id).decrement().toString());
        // 将减完的库存放到缓存中
        seckillGoods.setStockCount(decrement);
        redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).put(id,seckillGoods);
        if (seckillGoods.getStockCount() <= 0) {
            seckillGoodsMapper.updateByPrimaryKeySelective(seckillGoods);
            redisTemplate.boundHashOps(RedisSeckillGoods.SECKILL_GOODS).delete(id);
        }
        SekillIdAndUserId idAndUserId = new SekillIdAndUserId();
        idAndUserId.setId(id);
        idAndUserId.setUserId(userId);
        // 保存订单
        rocketMQTemplate.convertAndSend("sekillOrder",idAndUserId);
    }

    @Override
    public void saveOrder(Long id, Long userId) {
        TbSeckillOrder order = new TbSeckillOrder();
        TbSeckillGoods seckillGoods = getSeckillGoodsById(id);
        IdWorker idWorker = new IdWorker();
        order.setId(idWorker.nextId());
        order.setCreateTime(new Date());
        order.setMoney(seckillGoods.getCostPrice());
        order.setSeckillId(seckillGoods.getId());
        order.setUserId(userId.toString());
        order.setSellerId(seckillGoods.getSellerId());
        order.setStatus("0"); //  待支付
        orderMapper.insertSelective(order);
        redisTemplate.boundHashOps("sekillOrder").put(userId,order);
    }

    @Override
    public TbSeckillOrder getSeckillORderByUserId(Long userId) {
        return (TbSeckillOrder) redisTemplate.boundHashOps("sekillOrder").get(userId);
    }

    @Override
    public int updateSekillOrderStatus(String out_trade_no) {
        long id = Long.parseLong(out_trade_no);
        TbSeckillOrder seckillOrder = orderMapper.selectByPrimaryKey(id);
        seckillOrder.setStatus("1");
        seckillOrder.setPayTime(new Date());
        redisTemplate.boundHashOps("sekillOrder").put(seckillOrder.getUserId(),seckillOrder);
        return orderMapper.updateByPrimaryKeySelective(seckillOrder);
    }
}
